/**
 * 
 * @Project le cOeur - Data Virtualization
 * @Date 08.12.2012
 * @Author Aebi Pascal, Kocher Marc
 * @School BFH-TI Biel, Bachelor Thesis
 *
 */

package main.api.connection;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;

import main.api.security.KeyStoreManager;

/**
 * The class SocketFactory is used to create different sockets.
 */
public class SocketFactory {
	
	private KeyStoreManager keyStoreManager;
	
	/**
	 * Creates a socket factory.
	 * 
	 * @param keyStoreManager The key store manager.
	 */
	public SocketFactory(KeyStoreManager keyStoreManager){
		this.keyStoreManager = keyStoreManager;
	}
	
	/**
	 * Creates a socket depending on the given parameters and returns it.
	 * Depending on the given protocol a HTTP or a TLS socket is created.
	 * The port number dose not matter in this case.
	 * 
	 * @param protocol The protocol.
	 * @param host The host name, or null for the loopback address.
	 * @param port The port number.
	 * @return The corresponding socket.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws UnknownHostException If the host is not known.
	 * @throws IOException If an I/O error occurs. 
	 */
	public Socket createSocket(Protocol protocol, String host, int port) throws NoSuchAlgorithmException, KeyManagementException, UnknownHostException, IOException {
		// HTTPS
		if(protocol.equals(Protocol.TLS)){
	        SSLContext sslContext = SSLContext.getInstance("TLS");
	        sslContext.init(this.keyStoreManager.getKeyManagers(), this.keyStoreManager.getTrustManagers(), new SecureRandom());
	        SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(host, port);
	        sslSocket.startHandshake();
			return sslSocket;
		}
		// HTTP
		else{
			return new Socket(host, port);
		}
	}

}
